package com.hatricks.is.algorithm.quicksort;


public class QuickSort {
    /**
     * 快速排序主方法
     * @param arr 待排序数组
     */
    public static void quickSort(int[] arr) {
        // 检查数组是否为空或只有一个元素
        if (arr == null || arr.length <= 1) {
            return;
        }
        // 调用递归排序方法
        sort(arr, 0, arr.length - 1);
    }

    /**
     * 递归排序方法
     * @param arr 待排序数组
     * @param low 排序起始位置
     * @param high 排序结束位置
     */
    private static void sort(int[] arr, int low, int high) {
        // 递归终止条件：子数组长度为1或0
        if (low >= high) {
            return;
        }

        // 获取分区点索引
        int partitionIndex = partition(arr, low, high);

        // 递归排序左子数组（小于基准的部分）
         sort(arr, low, partitionIndex - 1);

        // 递归排序右子数组（大于基准的部分）
        sort(arr, partitionIndex + 1, high);
    }

    /**
     * 分区方法
     * @param arr 待分区数组
     * @param low 分区起始位置
     * @param high 分区结束位置
     * @return 基准元素的最终位置
     */
    private static int partition(int[] arr, int low, int high) {
        // 选择最右边的元素作为基准
        int pivot = arr[high];
        // i指向小于基准的区域的最后一个元素
        int i = low - 1;
        // 遍历数组，将小于基准的元素放到左边
        for (int j = low; j < high; j++) {
            if (arr[j] < pivot) {
                i++;
                // 交换arr[i]和arr[j]
                swap(arr, i, j);
            }
        }
        // 将基准放到正确的位置（i+1）
        swap(arr, i + 1, high);
        // 返回基准的最终位置
        return i + 1;
    }

    /**
     * 交换数组中两个元素的位置
     * @param arr 数组
     * @param i 第一个元素的索引
     * @param j 第二个元素的索引
     */
    private static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    public static void main(String[] args) {
        int[] arr = {10, 7, 8, 9, 1, 5};
        System.out.println("排序前:");
        printArray(arr);

        quickSort(arr);

        System.out.println("排序后:");
        printArray(arr);
    }

    /**
     * 打印数组
     * @param arr 要打印的数组
     */
    @SuppressWarnings("JavaExistingMethodCanBeUsed")
    private static void printArray(int[] arr) {
        for (int num : arr) {
            System.out.print(num + " ");
        }
        System.out.println();
    }
}
